<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // 什么叫闭包?
    // 闭包是指有权访问另一个函数作用域中变量的函数

    // 简单的来说: 函数在执行过程中返回了另一个函数,  (返回的函数中使用了父作用域的变量 => 父函数中的AO一直得不到释放 -> 可以长时间存储数据)

    // 如何形成闭包
    // 1. 函数在执行过程中返回了另一个函数或多个函数
    // 2. 返回的函数要使用父作用域中的变量
    // 3.  在函数的外部,有变量来引用返回的函数

    // 作用(优点):
    // 1. 长时间保存数据
    // 2. 减少全局变量的使用
    // 3. 可以函数外部访问函数内部的数据

    // 缺点:
    // 1. AO对象一直被引用,得不到释放 -> 占内存 , 如果应用过多,会导致内存泄露
    // 2. 函数外部访问函数内部的数据  => 不安全

    // 如果向以闭包的方式返回多个函数
    function fn() {  // AO = {a:10,func:func}
        var a = 10;  // 11   12 

        function addA() { // AO = {}
            a++;
            return a;  // 11
        }

        function reduceA() { // AO = {}
            a--;
            return a;  // 11
        }
        function doubleA() { // AO = {}
            a *= 2;
            return a;  // 11
        }

        return {
            "addA": addA,
            reduceA,
            doubleA,

            // 对 对象的"a"属性取值和赋值进行拦截
            get a() {  //对象的键名  => 取值
                return a;
            },
            set a(val) { //对象的键名  => 取值
                a = val;
            }

        };
    }

    var res = fn();
    console.log(res);

    // var result = res.addA();
    // console.log(result);
    // var result = res.addA();
    // console.log(result);
    // var result = res.addA();
    // console.log(result);
    // var result = res.addA();
    // console.log(result);


    // var result = res.reduceA();
    // console.log(result);
    // var result = res.reduceA();
    // console.log(result);
    // var result = res.reduceA();
    // console.log(result);
    // var result = res.reduceA();
    // console.log(result);

    // var result = res.doubleA();
    // console.log(result);



    res.addA()
    console.log(res.a);

    res.addA()
    console.log(res.a);

    res.addA()
    console.log(res.a);

    res.addA()
    console.log(res.a);


    res.a = 100;
    res.addA()
    console.log(res.a);








</script>

</html>